#include "dce.h"
#include <fcntl.h>
#include <iostream>
#include <string>
#include <fstream>
#include <pthread.h>

#include "group_id_message.h"
#include "gf_data_message.h"
#include "lf_data_message.h"
#include "text_label_message.h"
#include "color_label_message.h"
#include "npx_message.h"
#include "image_quality_message.h"
#include "image_splicing_message.h"
#include "a_image_message.h"
#include "dominant_color_message.h"
#include "TVMerage_SpiderAPI.h"
#include "NiuPixianAPI.h"
#include "Log.h"

#define THREAD_NUM 20

#define START_NUM 1
#define END_NUM
#define CALC_NUM   50000

using namespace std;

int read_image(const char *jpgfile, void *&buf)
{
	int fd = open( jpgfile, O_RDONLY );
	if( fd<0)
	{
		printf("Test image does not exist.\n");
		return -1;
	}
	struct stat  len_buf;
	fstat(fd, &len_buf);
	close(fd);
	int imageSize = len_buf.st_size;

	FILE *fp = fopen(jpgfile, "rb");
	buf = new unsigned char *[imageSize];
	fread(buf, 1, imageSize, fp);
	fclose(fp);
	return imageSize;
}

address addr("199.155.122.17", 40075);

timeval beg, end;
int cor_num = 0, err_num = 0;

pthread_mutex_t mutex;

vector<string > pic_list;
queue<string> pic_queue;

int calc_num;
void *send_thread(void *ptr)
{
	bool cor_flag = true;
	timeval thread_end;
	timeval temp_tv;
	LOG_INFO_VA("send thread start");
	server_proxy svr(addr);

	server_proxy::io_read_timeout  = 30000;
	server_proxy::io_write_timeout = 30000;
	//FILE *plist = fopen("pic_list.txt", "r");
/*
	cout <<"pic num:" << pic_list.size() << "; last is:" << pic_list.back() << endl;
	int first_p = pic_list.back().rfind('/');
	int last_p  = pic_list.back().find('.');
	//cout << "rfind: " << pic_list.back().rfind('/') << endl;
	//cout <<  "find: " << pic_list.back().find('.') << endl;
	//string sub_str =  pic_list.back().substr(string::rfind('/'), string::find('.'));
	string sub_str =  pic_list.back().substr(first_p+1, last_p-first_p-1);
	cout <<"sub str from "<<first_p <<" to " << last_p << " is: "<<  sub_str << endl;
	cout << "num is: " << atoi(sub_str.c_str()) << endl;
*/
	for(int i = 0; i < calc_num ;i++)
	{
		void *image_buf;
		
	pthread_mutex_lock(&mutex);
		int image_size = read_image(pic_queue.front().c_str(), image_buf);
		//int image_size = read_image("test.jpg", image_buf);
		if (image_size <= 0) {
			LOG_ERROR_VA("bad jpg file");
			return NULL;
		}
		
		int first_p = pic_queue.front().rfind('/');
		int last_p  = pic_queue.front().find('.');
		string sub_str =  pic_queue.front().substr(first_p+1, last_p-first_p-1);
		
		string temp_pic;
		temp_pic = pic_queue.front();
		if(pic_queue.size() != 1){
			pic_queue.pop();
			pic_queue.push(temp_pic);
		}else{
			LOG_INFO_VA("calc over !");
			pthread_mutex_unlock(&mutex);
			pthread_exit(0);
		}
	pthread_mutex_unlock(&mutex);

		LOG_INFO_VA("the image_id is %s", sub_str.c_str());
/*		
		group_id_request_message grp_req;
		group_id_response_message grp_res;
		//grp_req.set_image_id(11111);

		gettimeofday(&temp_tv, 0);
		srand(temp_tv.tv_usec);
		grp_req.set_sn_high(rand());
		grp_req.set_sn_low(rand());
		LOG_DEBUG_VA("grp message sn-sn:%llu-%llu ", grp_req.get_head().sn_high,grp_req.get_head().sn_low);

		grp_req.set_image_id(atoi(sub_str.c_str()));
		grp_req.set_class_id(7);
		grp_req.set_subclass_id(70020);
		grp_req.set_image_data_size(image_size);
		grp_req.set_image_data(image_buf);
		if (svr.request(grp_req, grp_res) != 0 || grp_res.unnormal()) {
			LOG_ERROR_VA("grp request error");
			cor_flag = false;
			__sync_add_and_fetch(&err_num, 1);
		}
*/
/*		
		lf_data_request_message lf_req;
		lf_data_response_message lf_res;
		
		gettimeofday(&temp_tv, 0);
		srand(temp_tv.tv_usec);
		lf_req.set_sn_high(rand());
		lf_req.set_sn_low(rand());
		LOG_DEBUG_VA("lf_data message sn-sn:%llu-%llu ", lf_req.get_head().sn_high, lf_req.get_head().sn_low);

		lf_req.set_image_data_size(image_size);
		lf_req.set_image_data(image_buf);
		if (svr.request(lf_req, lf_res) != 0 || lf_res.unnormal()) {
			LOG_ERROR_VA("lf request error");
			cor_flag = false;
			__sync_add_and_fetch(&err_num, 1);
		}
*/
		gf_data_request_message gf_req;
		gf_data_response_message gf_res;
		
		gettimeofday(&temp_tv, 0);
		srand(temp_tv.tv_usec);
		gf_req.set_sn_high(rand());
		gf_req.set_sn_low(rand());
		LOG_DEBUG_VA("gf_data message sn-sn:%llu-%llu ", gf_req.get_head().sn_high, gf_req.get_head().sn_low);

		gf_req.set_image_data_size(image_size);
		gf_req.set_image_data(image_buf);
		if (svr.request(gf_req, gf_res) != 0 || gf_res.unnormal()) {
			LOG_ERROR_VA("gf request error");
			cor_flag = false;
			__sync_add_and_fetch(&err_num, 1);
		}

	
		color_label_request_message cl_req;
		color_label_response_message cl_res;
		
		gettimeofday(&temp_tv, 0);
		srand(temp_tv.tv_usec);
		cl_req.set_sn_high(rand());
		cl_req.set_sn_low(rand());
		LOG_DEBUG_VA("color_label message sn-sn:%llu-%llu ", cl_req.get_head().sn_high, cl_req.get_head().sn_low);

		cl_req.set_image_data_size(image_size);
		cl_req.set_image_data(image_buf);
		if (svr.request(cl_req, cl_res) != 0 || cl_res.unnormal()) {
			LOG_ERROR_VA("color request error");
			cor_flag = false;
			__sync_add_and_fetch(&err_num, 1);
		}

/*	
		npx_request_message npx_req;
		npx_response_message npx_res;
		
		gettimeofday(&temp_tv, 0);
		srand(temp_tv.tv_usec);
		npx_req.set_sn_high(rand());
		npx_req.set_sn_low(rand());
		LOG_DEBUG_VA("npx message sn-sn:%llu-%llu ", npx_req.get_head().sn_high, npx_req.get_head().sn_low);

		npx_req.set_image_data_size(image_size);
		npx_req.set_image_data(image_buf);
		if (svr.request(npx_req, npx_res) != 0 || npx_res.unnormal()) {
			LOG_ERROR_VA("npx request error");
			cor_flag = false;
			__sync_add_and_fetch(&err_num, 1);
		}

		image_quality_request_message iq_req;
		image_quality_response_message iq_res;
		
		gettimeofday(&temp_tv, 0);
		srand(temp_tv.tv_usec);
		iq_req.set_sn_high(rand());
		iq_req.set_sn_low(rand());
		LOG_DEBUG_VA("iq message sn-sn:%llu-%llu ", iq_req.get_head().sn_high, iq_req.get_head().sn_low);

		iq_req.set_image_data_size(image_size);
		iq_req.set_image_data(image_buf);

		if (svr.request(iq_req, iq_res) != 0 || iq_res.unnormal() ) {
			LOG_ERROR_VA("iq request error");
			cor_flag = false;
			__sync_add_and_fetch(&err_num, 1);
		}

		image_splicing_request_message is_req;
		image_splicing_response_message is_res;
		
		gettimeofday(&temp_tv, 0);
		srand(temp_tv.tv_usec);
		is_req.set_sn_high(rand());
		is_req.set_sn_low(rand());
		LOG_DEBUG_VA("is message sn-sn:%llu-%llu ", is_req.get_head().sn_high, is_req.get_head().sn_low);

		is_req.set_image_id(atoi(sub_str.c_str()));
		is_req.set_class_id(70020);
		is_req.set_image_data_size(image_size);
		is_req.set_image_data(image_buf);

		if (svr.request(is_req, is_res) != 0 || is_res.unnormal() ) {
			LOG_ERROR_VA("is request error");
			cor_flag = false;
			__sync_add_and_fetch(&err_num, 1);
		}

		a_image_request_message ai_req;
		a_image_response_message ai_res;
		
		gettimeofday(&temp_tv, 0);
		srand(temp_tv.tv_usec);
		ai_req.set_sn_high(rand());
		ai_req.set_sn_low(rand());
		LOG_DEBUG_VA("ai message sn-sn:%llu-%llu ", ai_req.get_head().sn_high, ai_req.get_head().sn_low);

		ai_req.set_image_id(atoi(sub_str.c_str()));
		ai_req.set_class_id(70020);
		ai_req.set_image_data_size(image_size);
		ai_req.set_image_data(image_buf);

		if (svr.request(ai_req, ai_res) != 0 || ai_res.unnormal() ) {
			LOG_ERROR_VA("ai request error");
			cor_flag = false;
			__sync_add_and_fetch(&err_num, 1);
		}
		
		dominant_color_request_message dc_req;
		dominant_color_response_message dc_res;
		
		gettimeofday(&temp_tv, 0);
		srand(temp_tv.tv_usec);
		dc_req.set_sn_high(rand());
		dc_req.set_sn_low(rand());
		LOG_DEBUG_VA("ai message sn-sn:%llu-%llu ", dc_req.get_head().sn_high, dc_req.get_head().sn_low);

		dc_req.set_image_id(atoi(sub_str.c_str()));
		dc_req.set_class_id(70020);
		dc_req.set_image_data_size(image_size);
		dc_req.set_image_data(image_buf);

		if (svr.request(dc_req, dc_res) != 0 || dc_res.unnormal() ) {
			LOG_ERROR_VA("ai request error");
			cor_flag = false;
			__sync_add_and_fetch(&err_num, 1);
		}


		int text_count = 1;
		int text_types[5] = { 0, 1, 2, 3, 4};
		char texts[5][256] = {"高跟","雪地靴","黑色", "斑点", "花边"};
		char texts_1[5][256] = {
			"SZ3111韩版修身显瘦拼皮长袖连衣裙（黑色\\杏色）sy",
			"黑色斑点花边雪地靴高跟长袖立领",
			"条纹格子纯色卡通拼色",
			"消息状态，请求和通知类型中取值0",
			"小白兔毛是白的马海毛"
		};
		char texts_2[5][256] = {"长袖","立领","黑色", "斑点", "花边"};
		
		strTextInfo *text = new strTextInfo[5];
		//cout << "size of strtextInfo:" << sizeof(strTextInfo) << endl;
		memset(text, 0, 5 * sizeof(strTextInfo) );
		for(int j = 0; j != 5; j++){
			text[j].type_source = 0;
			memcpy(text[j].text, texts_1[j], 256);
			//the input texts
		}
		text_label_request_message tl_req;
		text_label_response_message tl_res;

		gettimeofday(&temp_tv, 0);
		srand(temp_tv.tv_usec);
		tl_req.set_sn_high(rand());
		tl_req.set_sn_low(rand());
		LOG_DEBUG_VA("tl message sn-sn:%llu-%llu ", tl_req.get_head().sn_high, tl_req.get_head().sn_low);

		tl_req.set_text_count(1);
		tl_req.set_texts(text);
		tl_req.set_class_id(7);
		tl_req.set_subclass_id(70020);
		//tl_req.set_text_data_size(5 * 256);
		//tl_req.set_text_data(texts);
		if (svr.request(tl_req, tl_res) != 0 || tl_res.unnormal()) {
			LOG_ERROR_VA("text request error");
			cor_flag = false;
			__sync_add_and_fetch(&err_num, 1);
		}
*/	
		if(cor_flag)
			__sync_add_and_fetch(&cor_num, 1);
		
		gettimeofday(&thread_end, 0);
		delete[] image_buf;
	
		if((thread_end.tv_usec - beg.tv_usec)/1000000 + (thread_end.tv_sec - beg.tv_sec) > 1)
			cout << "dump client time: " << (thread_end.tv_usec - beg.tv_usec)/1000000 + (thread_end.tv_sec - beg.tv_sec)
				<< "s; tps: "<< cor_num /( (thread_end.tv_usec - beg.tv_usec)/1000000 + thread_end.tv_sec - beg.tv_sec )
				<< "; image_id: " << sub_str << "; correct: "<< cor_num << "; error: "<< err_num << endl;
		//if((thread_end.tv_usec - beg.tv_usec)/1000000 + (thread_end.tv_sec - beg.tv_sec) > 550)
		//	pthread_exit(0);
	}
}

int main(int argc, char **argv)
{
	gettimeofday(&beg, 0);

	init_logger("./logdump", "TRACE");
	LOG_INFO_VA("main start");
	
	string filename = "pic_list.txt";
	string lines;
	ifstream in(filename.c_str());
/*	if(in){
		while(getline (in , lines)){
			pic_list.push_back(lines);
		#ifdef CALC_NUM
			if(pic_list.size() == CALC_NUM)
			  break;
		#endif
		}
	}else{
		cout << "open failed" << endl;
	}
*/
	int num = 0;
	if(in){
		while(getline (in , lines)){
			if(num > START_NUM && num < START_NUM + CALC_NUM)
				pic_queue.push(lines);
			num ++;
			if(pic_queue.size() == CALC_NUM)
				break;
		}
	}else{
		cout << "open failed" << endl;
	}

	cout <<"pic nums: " << pic_queue.size() << endl; 
	calc_num = pic_queue.size();

	pthread_mutex_init(&mutex, NULL);

	pthread_t tid[THREAD_NUM];
	for(int i = 0;i < THREAD_NUM;i++)
	{
		pthread_create(&tid[i], NULL, send_thread, NULL);
	}
	
	for(int i = 0;i < THREAD_NUM;i++)
	{
		pthread_join(tid[i], NULL);
	}
	gettimeofday(&end, 0);
	
	cout << "dump client time: " << (end.tv_usec - beg.tv_usec)/1000000 + end.tv_sec - beg.tv_sec << " s"
		"tps: "<<cor_num /( (end.tv_usec - beg.tv_usec)/1000000 + end.tv_sec - beg.tv_sec )<< endl;
	
	return 0;
}
